home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
manchest.lha
/
MANCHESTER
/
manchester
/
4.1
/
SunFunKeys.st
< prev
next >
Wrap
Text File
|
1993-07-24
|
18KB
|
530 lines
" NAME SunFunKeys4.1
AUTHOR Markus Geltz, Alan Wills, Mario Wolczko
FUNCTION Binds functions to keys on the SUN type-4 keyboard
ST-VERSION 4.1
PREREQUISITES
CONFLICTS
DISTRIBUTION world
VERSION 4
DATE 28 May 1993
SUMMARY
This goodie binds various function keys appropriately on the Sun Type 4
keyboard. Other keyboards can be handled with small modifications.
A text search feature is also included.
The bindings are:
Again(L2), Undo(L4), Copy(L6), Paste(L8), Cut(L10): as you'd expect.
Find(L9):
if there is a selection, finds its next occurrence;
othewise, finds a string as you type it
--- any non-printing key gets out of this mode.
Two successive L9's look for the most recently found string.
Enter: Accept
Home(R7): beginning of line; End(R13): end of line.
PgUp(R9), PgDn(R15): prior and next pages.
R1, R2, R3: do it, print it, inspect it.
LineFeed: newline and copy indentation from previous line.
Help: tells you the Smalltalk code and binding for the next keystroke.
It should be obvious how to bind other keys following this scheme.
In general:
1. Ensure that your window system is mapping the key to a key symbol.
Use the Help key as above, or use 'KBMonitor open'.
If not, use xmodmap to achieve the mapping. xev is a useful program for
finding which keycode is generated by a key.
Names of X11 keysyms can usually be found in /usr/include/X11/keysymdef.h
and InputState class>initKeys.
2. Add a suitable line to ParagraphEditor>initializeSUNkeys to associate the keysym
with a method. Write the method if necessary.
3. Reinitialize ParagraphEditor. New windows will use the new mapping.
"!
'From Objectworks\Smalltalk(R), Release 4.1 of 15 April 1992 on 27 May 1993 at 2:47:43 am'!
ControllerWithMenu subclass: #ParagraphEditor
instanceVariableNames: 'beginTypeInIndex emphasisHere dispatchTable charComposer textHasChanged '
classVariableNames: 'CodeYellowButtonMenu CompilationErrorSignal Keyboard MostRecentSearchString PreviousSelections TextEditorYellowButtonMenu UndoSelection '
poolDictionaries: 'TextConstants '
category: 'Interface-Text'!
!ParagraphEditor methodsFor: 'editing'!
againKey: aChar
"Repeat the last edit"
self again!
beginOfTextKey: aChar
".Creator: Markus Geltz Last Modified: 24 October 1991 6:08:41 pm."
"set the carat to the begin of the text"
self selectionStartIndex: 1.
self selectionStopIndex: 1.
view selectAndScroll.
^ true!
copySelectionKey: aChar
"Copy the current text selection."
self copySelection!
deleteBackwardWordKey: aChar
".Creator: Markus Geltz Last Modified: 17 September 1991 1:44:25 pm."
"delete one word backward"
| wordIndices start |
self selectionStopIndex: (start := self selectionStartIndex).
start > 1 ifFalse: [^ true].
wordIndices := self getWordBoundsWithIndex: start direction: #back.
self selectionStartIndex: wordIndices first.
self cut.
view selectAndScroll.
^true!
deleteForwardCharKey: aChar
".Creator: Markus Geltz Last Modified: 17 September 1991 4:35:22 pm."
"delete one character forward"
| stopIndex |
self resetTypein.
stopIndex := self text size min: self selectionStopIndex + 1.
self selectionStopIndex: stopIndex.
self replaceSelectionWith: Text new.!
deleteForwardWordKey: aChar
".Creator: Markus Geltz Last Modified: 17 September 1991 1:44:34 pm."
"delete one word forward"
| wordIndices start |
self selectionStopIndex: (start := self selectionStartIndex).
start < self text size ifFalse: [^ true].
wordIndices := self getWordBoundsWithIndex: start direction: #for.
self selectionStopIndex: wordIndices last.
self cut.
view selectAndScroll.
^true!
doItKey: aChar
self doIt!
echoInputKey: aCharEvent
"A bizarre character has been received: echo its value to the Transcript, but ignore it otherwise."
Transcript show: 'Unknown key: ',aCharEvent keyValue printString; cr.
self ignoreInputKey: aCharEvent!
endOfTextKey: aChar
".Creator: Markus Geltz Last Modified: 24 October 1991 6:11:06 pm."
"set the carat to the begin of the text"
| size |
size := self text size + 1.
self selectionStartIndex: size.
self selectionStopIndex: size.
view selectAndScroll.
^ true!
findEndKey: aChar
"A funny key during a search --- see findKey:"
self selectionStopIndex = self selectionStartIndex
ifTrue: [ aChar keyValue = #L9
ifTrue: [self findAndSelect: MostRecentSearchString.
self selectionStopIndex = self selectionStartIndex
ifTrue: [self selectionStopIndex: 1.
self selectionStartIndex: 1.
self findAndSelect: MostRecentSearchString] ]]
ifFalse:[MostRecentSearchString := self selection asString].
dispatchTable := nil "will revert to default"!
findExtendKey: aChar
"In the middle of a search --- see findeKey"
| sti |
sti := self selectionStopIndex.
(self text size < sti ifTrue: [nil] ifFalse: [self text at: sti]) = aChar keyValue
ifTrue: [self selectFrom: self selectionStartIndex to: sti]
ifFalse: [ self findAndSelect: (self selection asString copyWith: aChar keyValue)]!
findKey: aChar
"Search for the next occurrence of the string under the cursor"
"Alan Wills <alan@cs.man.ac.uk>"
| ss |
self searchKey: aChar
"ss := self selectionStartIndex.
ss = self selectionStopIndex
ifTrue: [ dispatchTable := DispatchTable new.
dispatchTable defaultForCharacters: #findExtendKey: ;
defaultForNonCharacters: #findEndKey: ]
ifFalse: [ self findAndSelect: (MostRecentSearchString := self selection asString).
ss = self selectionStartIndex ifTrue: [
self selectFrom: 1 to: 0.
self findAndSelect: MostRecentSearchString]]"!
searchKey: c
| ss sti done |
ss := self selectionStartIndex.
ss = self selectionStopIndex
ifFalse: [self findAndSelect: (MostRecentSearchString := self selection asString).
ss = self selectionStartIndex ifTrue: [
self selectFrom: 1 to: 0.
self findAndSelect: MostRecentSearchString]]
ifTrue: [ Cursor crossHair showWhile: [
[done isNil & self viewHasCursor and: [self sensor anyButtonPressed not]] whileTrue: [
self dispatchTable add: self sensor keyboardEvent do: [
:cev :sel |
sel == #normalCharacterKey:
ifTrue: [
sti := self selectionStopIndex.
(self text size < sti ifTrue: [nil] ifFalse: [self text at: sti]) = cev keyValue
ifTrue: [self selectFrom: self selectionStartIndex to: sti]
ifFalse: [ self findAndSelect: (self selection asString copyWith: cev keyValue)]]
ifFalse: [self selectionStopIndex = self selectionStartIndex
ifTrue: [ cev keyValue = #L9
ifTrue: [self findAndSelect: MostRecentSearchString ]]
ifFalse:[MostRecentSearchString := self selection asString].
done := true] ]] ] ] !
flipChars: aStream key: aChar
".Creator: Markus Geltz Last Modified: 29 October 1991 5:04:25 pm."
"flip the two characters before and after the caret"
| before after ind |
(ind :=self selectionStartIndex) = self selectionStopIndex
ifFalse: [^ true].
self selectionStartIndex: ind - 1.
before := (paragraph characterBlockForIndex: ind - 1) character.
after := (paragraph characterBlockForIndex: ind) character.
self replaceFrom: ind - 1 to: ind with: (Text fromString: after asSymbol , before asSymbol).
self selectionStartIndex: ind.
view selectAndScroll.
^ true!
flipCharsKey: aChar
".Creator: Markus Geltz Last Modified: 29 October 1991 5:04:25 pm."
"flip the two characters before and after the caret"
| before after ind |
(ind :=self selectionStartIndex) = self selectionStopIndex
ifFalse: [^ true].
self selectionStartIndex: ind - 1.
before := self text at: ind - 1.
after := self text at: ind.
self replaceFrom: ind - 1 to: ind with: (Text fromString: after asSymbol , before asSymbol).
self selectionStartIndex: ind.
view selectAndScroll.
^ true!
forwardWord: characterStream key: aChar
".Creator: Markus Geltz Last Modified: 17 September 1991 1:44:47 pm."
"set Cursor one word forward"
| wordIndices start |
start := self selectionStartIndex.
start < paragraph string size ifFalse: [^ true].
wordIndices := self getWordBoundsWithIndex: start direction: #for.
self selectionStartIndex: wordIndices last.
self selectionStopIndex: wordIndices last.
view selectAndScroll.
^true!
forwardWordKey: aChar
".Creator: Markus Geltz Last Modified: 17 September 1991 1:44:47 pm."
"set Cursor one word forward"
| wordIndices start |
start := self selectionStartIndex.
start < self text size ifFalse: [^ true].
wordIndices := self getWordBoundsWithIndex: start direction: #for.
self selectionStartIndex: wordIndices last.
self selectionStopIndex: wordIndices last.
view selectAndScroll.
^true!
helpKey: aChar
| c purpose |
c := self sensor keyboardEvent.
purpose := self dispatchTable lookup: c keyValue meta: c metaState.
purpose = #echoInputKey: ifTrue: [purpose := ' not used '].
DialogView warn: c keyValue printString, ' ', purpose.!
indentedCRKey: aChar
"Replace the current text selection with a CR plus
the number of tabs and spaces found at the beginning of
the current line."
"Based on a (rather inefficient) version from ParcPlace."
| text index character characterStream ssi |
"Sniff backwards along text string till CR or beginning of string."
text := self paragraph text.
index := ssi := self selectionStartIndex.
"test for empty text"
index = 1 ifTrue: [self appendToSelection: (String with: CR). ^self].
character := nil.
[index := index - 1.
character := text at: index.
character = CR or: [index = 1]]
whileFalse.
"Special exit for immediate encounter of CR."
(ssi - 1 = index)
ifTrue: [self appendToSelection: (String with: CR). ^self].
"Now accumulate whitespace into characterStream till first non-white
character, or end of string."
characterStream := (String new: 8) writeStream.
characterStream nextPut: CR.
character == CR ifTrue: [index := index + 1].
character := text at: index.
[character = Tab | (character = Space) & (index < ssi)]
whileTrue:
[characterStream nextPut: character.
index := index + 1.
index < ssi ifTrue: [character := text at: index]].
self appendToSelection: characterStream contents!
inspectItKey: aChar
self inspectIt!
printItKey: aChar
self printIt!
selectWordKey: aChar
| s |
s := self selectWord: self selectionStartIndex.
self selectFrom: s first to: s last! !
!ParagraphEditor methodsFor: 'private - editing'!
getWordBoundsWithIndex: index direction: aSymbol
".Creator: Markus Geltz Last Modified: 14 October 1991 12:36:26 pm."
"returns the word bounds of the word next to index anInteger. direction should
be the symbol #back or #for"
| direction level string here hereChar start |
string := self text string.
here := index.
aSymbol = #back
ifTrue: [direction := -1]
ifFalse: [direction := 1].
[hereChar := string at: (here := here + direction).
hereChar isAlphaNumeric not]
whileTrue.
direction := -1.
level := 1.
[level > 0 and: [direction > 0
ifTrue: [here < string size]
ifFalse: [here > 1]]]
whileTrue:
[hereChar := string at: (here := here + direction).
"token scan goes left, then right"
hereChar tokenish
ifTrue: [here = 1
ifTrue:
[start := 1.
"go right if hit string start"
direction := 1]]
ifFalse: [direction < 0
ifTrue:
[start := here + 1.
"go right if hit non-token"
direction := 1]
ifFalse: [level := 0]]].
level > 0 ifTrue: ["in case ran off string end" here := here + direction].
^ start to: here! !
!ParagraphEditor class methodsFor: 'class initialization'!
expandDispatchTable
".Creator: Markus Geltz Last Modified: 4 November 1991 3:56:46 pm."
"expand the keyboard dispatch table"
"ParagraphEditor expandDispatchTable."
(DialogView confirm: 'Do you want ctrl/t and ctrl/f to be flip and forward?')
ifFalse: [^self].
Keyboard bindValue: #homeKey: to: Ctrla.
Keyboard bindValue: #deleteForwardCharKey: to: Ctrld.
Keyboard bindValue: #endKey: to: Ctrle.
Keyboard bindValue: #cursorRightKey: to: Ctrlf.
Keyboard bindValue: #cursorLeftKey: to: Ctrlb.
Keyboard bindValue: #cursorUpKey: to: Ctrlp.
Keyboard bindValue: #cursorDownKey: to: Ctrln.
Keyboard bindValue: #beginOfTextKey: to: ESC followedBy: $<.
Keyboard bindValue: #endOfTextKey: to: ESC followedBy: $>.
Keyboard bindValue: #flipCharsKey: to: Ctrlt.
Keyboard
bindValue: #forwardWordKey:
to: ESC
followedBy: $f.
Keyboard
bindValue: #backWordKey:
to: ESC
followedBy: $b.
Keyboard
bindValue: #deleteForwardWordKey:
to: ESC
followedBy: $d.
Keyboard
bindValue: #deleteBackwardWordKey:
to: ESC
followedBy: Cut!
initialize
"Initialize the yellow button menu information, the keyboard map for special
control characters, and the shared buffers for copying text across views and
managing undo."
"ParagraphEditor initialize."
PreviousSelections := OrderedCollection with: ' ' asText.
self currentSelection: (self undoSelection: Text new).
TextEditorYellowButtonMenu :=
PopUpMenu labels: 'again\undo\copy\cut\paste\accept\cancel' withCRs
lines: #(2 5 )
values: #(again undo copySelection cut paste accept cancel).
CodeYellowButtonMenu :=
PopUpMenu
labelList: #((again undo) (copy cut paste) ('do it' 'print it' 'inspect') (accept cancel) (hardcopy))
values: #(again undo copySelection cut paste doIt printIt inspectIt accept cancel hardcopy).
MostRecentSearchString := ''.
self initializeDispatchTable.
self expandDispatchTable.
self initializeSUNKeys.
CompilationErrorSignal := (self errorSignal newSignalMayProceed: true)
notifierString: 'Compilation failed';
nameClass: self message: #compilationErrorSignal.!
initializeDispatchTable
"Initialize the keyboard dispatch table."
"ParagraphEditor initializeDispatchTable."
Keyboard := DispatchTable new.
Keyboard defaultForCharacters: #normalCharacterKey:.
Keyboard defaultForNonCharacters: #echoInputKey:.
Keyboard bindValue: #backspaceKey: to: Cut.
Keyboard bindValue: #pasteKey: to: Paste.
Keyboard bindValue: #backspaceKey: to: BS.
Keyboard bindValue: #backWordKey: to: Ctrlw.
Keyboard bindValue: #displayIfTrueKey: to: Ctrlt.
Keyboard bindValue: #displayIfFalseKey: to: Ctrlf.
Keyboard bindValue: #displayDateKey: to: Ctrld.
Keyboard bindValue: #displayColonEqualKey: to: Ctrlg.
"Keyboard bindValue: #displayCRKey: to: #Enter."
Keyboard bindValue: #cursorUpKey: to: #Up.
Keyboard bindValue: #cursorDownKey: to: #Down.
Keyboard bindValue: #cursorLeftKey: to: #Left.
Keyboard bindValue: #cursorRightKey: to: #Right.
Keyboard bindValue: #homeKey: to: #Home.
Keyboard bindValue: #endKey: to: #End.
Keyboard bindValue: #pageUpKey: to: #PageUp.
Keyboard bindValue: #pageDownKey: to: #PageDown.
'<''"[{(' do:
[:char |
Keyboard
bindValue: #encloseKey:
to: ESC
followedBy: char].
'sSuUbBiIx+-' do:
[:char |
Keyboard
bindValue: #changeEmphasisKey:
to: ESC
followedBy: char].
Keyboard
bindValue: #miniFormatKey:
to: ESC
followedBy: $f.
Keyboard
bindValue: #selectCurrentTypeInKey:
to: ESC
followedBy: Tab.
Keyboard
bindValue: #selectCurrentTypeInKey:
to: #F1!
initializeSUNKeys
"Initialize the mapping for function keys on the SUN type-4 keyboard."
"ParagraphEditor initializeSUNKeys"
Keyboard bindValue: #indentedCRKey: to: LF.
Keyboard bindValue: #againKey: to: #L2.
Keyboard bindValue: #undoKey: to: #L4.
Keyboard bindValue: #copySelectionKey: to: #L6.
Keyboard bindValue: #pasteKey: to: #L8.
Keyboard bindValue: #cutKey: to: #L10.
Keyboard bindValue: #doItKey: to: #R1.
Keyboard bindValue: #printItKey: to: #R2.
Keyboard bindValue: #inspectItKey: to: #R3.
Keyboard bindValue: #acceptKey: to: #Enter.
Keyboard bindValue: #homeKey: to: #R7.
Keyboard bindValue: #endKey: to: #R13.
Keyboard bindValue: #pageUpKey: to: #R9.
Keyboard bindValue: #pageDownKey: to: #R15.
Keyboard bindValue: #findKey: to: #L9.
Keyboard bindValue: #selectWordKey: to: #R11.
Keyboard bindValue: #helpKey: to: #Help.! !
ParagraphEditor initialize!
ParagraphEditor subclass: #KeyStrokeMonitor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Interface-Text'!
!KeyStrokeMonitor methodsFor: 'editing'!
readKeyboard
"Read the keyboard and dispatch the keyboard events."
"This method checks the Symbol returned by the dispatchTable and checks to see if it is
"
self deselect.
self sensor keyboardPressed ifTrue:
[
self dispatchTable
add: self sensor keyboardEvent do:
[:charEvent :sel | self selectFrom: 1 to: self text string size + 1.
self performPasteAction: charEvent keyValue printString
]].
view selectAndScroll! !
!KeyStrokeMonitor methodsFor: 'plugging'!
menu
^PopUpMenu labels: 'ceci n''est pas une carte'!
starttext
^ ''! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
KeyStrokeMonitor class
instanceVariableNames: ''!
!KeyStrokeMonitor class methodsFor: 'instance creation'!
open
"KeyStrokeMonitor open"
"Use this to see what codes to set in the ParagraphEditor dispatch table
--- each keystroke typed at this window shows its key value."
| km dc tv win |
km := self new.
dc := DependentComposite new.
tv := TextView on: km aspect: #starttext change: #t:from: menu: #menu initialSelection: nil.
dc add: (LookPreferences edgeDecorator on: tv) in: (0@0 corner: 1.0@1.0).
tv controller: km.
win := ScheduledWindow model: km label: 'KB Monitor' minimumSize: 110@30.
win maximumSize: win minimumSize.
win component: dc.
win open.
^self! !